package api

import (
	"bufio"
	"fmt"
	"goexample.com/vulscaner/common"
	"io"
	"log"
	"os"
	"os/exec"
	"strconv"
)

var (
	cmdChan     = make(chan bool, 1)
	messageChan = make(chan string, 100)
	sseId       = 0
	CmdStatus   bool
	result      string
)

func getOut(stdout io.ReadCloser) string {
	reader := bufio.NewReader(stdout)
	var totalOutput string
	for {
		readString, err := reader.ReadString('\n')
		if err != nil || err == io.EOF {
			break
		}
		sseId++
		messageChan <- readString
		totalOutput = totalOutput + readString
		result = totalOutput
	}
	return totalOutput
}

func CmdDone() bool {
	if CmdStatus {
		select {
		case <-cmdChan:
			CmdStatus = false
			return true
		default:
			return false
		}
	} else {
		return true
	}
}

func fscanStarter(taskID int, cidrIp string) {
	logFileName := common.GenLogFileName("fscan", cidrIp)
	fscanLogFilePath := common.AbsolutPath() + "/log/fscan/" + logFileName
	execPath := common.AbsolutPath() + "/static/fscan.exe"
	fscanArg := []string{"-h", cidrIp, "-o", fscanLogFilePath}
	// 调试模式跳过poc扫描和弱口令爆破
	if common.DEBUG_MODE {
		fscanArg = []string{"-nobr", "-nopoc", "-h", cidrIp, "-o", fscanLogFilePath}
	}
	fscanCmdline := common.Arg2String(execPath, fscanArg)
	common.UpdatePath(taskID, "fscan_logfile", logFileName)
	com := exec.Command("cmd", "/C", fscanCmdline)
	stdout, _ := com.StdoutPipe()
	// go io.Copy(os.Stdout, stdout)
	go getOut(stdout)
	err := com.Run()
	if err != nil {
		fmt.Println(err)
		return
	}

	// webURLs := common.WebResultFilter(fscanLogFilePath)
	// xrayStarter(taskID, webURLs)
	cmdChan <- true
	log.Print("Task" + strconv.Itoa(taskID) + ": Done!")
}

func xrayStarter(taskID int, urls []string) {
	taskTime := common.TaskTime(taskID)
	taskDir := common.AbsolutPath() + "/log/xray/" + taskTime + "/"
	err := os.Mkdir(taskDir, os.ModePerm)
	if err != nil {
		return
	}
	for _, url := range urls {
		xrayLogFilePath := taskDir + common.GenLogFileName("xray", url)
		xrayHtmlFilePath := taskDir + common.GenLogFileName("xray", url) + ".html"
		execPath := common.AbsolutPath() + "/static/xray/xray.exe"
		xrayArg := []string{"webscan", "--basic-crawler", url, "--html-output", xrayHtmlFilePath}
		xrayCmdline := common.Arg2String(execPath, xrayArg)

		com := exec.Command("cmd", "/C", xrayCmdline)
		com.Dir = common.AbsolutPath() + "/static/xray/"
		com.Env = append(com.Environ(), "POSIXLY_CORRECT=1")
		stdout, _ := com.StdoutPipe()
		err := com.Start()
		xrayOutput := getOut(stdout)
		if err != nil {
			fmt.Println(err)
			return
		}

		file, errf := os.Create(xrayLogFilePath)
		if errf != nil {
			fmt.Println(err)
			return
		}
		fmt.Fprintf(file, xrayOutput)
		file.Close()
	}
	result = result + "\nDone!"
}

func ExecScan(cidrIp string) {
	//开始扫描任务前清空输出
	result = ""
	sseId = 0
	CmdStatus = true
	id := common.GenTaskID(cidrIp)
	if id != -1 {
		go fscanStarter(id, cidrIp)
	} else {
		log.Fatalln("Gen Task id Fail")
	}
}
